home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 November: Tool Chest / Dev.CD Nov 94.toast / Sample Code / Snippets / Toolbox / MModal 7.0 / MModal 7.0.c next >
Encoding:
C/C++ Source or Header  |  1992-07-15  |  23.9 KB  |  680 lines  |  [TEXT/MPS ]

  1. /* MModal.c */
  2. /* The simplest C System 7 shell application */
  3. /* Modified to show a simple Moveable Modal window */
  4.  
  5. /* This shell can be very handy for debugging and testing things */
  6. /* Add menu items, add dialogs, add controls, or whatever else you need */
  7. /* This sample contains basic application startup and event loop handling, */
  8. /* add more features as your needs increase. */
  9. /* This sample is High Level Event aware, so you can send and receive AppleEvents */
  10. /* from this application */
  11. /* Written by C.K. Haun <TR> */
  12. /* Apple Developer Tech Support */
  13. /* October 1991, Tokyo, Japan */
  14. /* Of course, Copyright 1991-1992, Apple Computer Inc. */
  15.  
  16.  
  17. #include <Types.h>
  18. #include <memory.h>
  19. #include <Packages.h>
  20. #include <Errors.h>
  21. #include <quickdraw.h>
  22. #include <fonts.h>
  23. #include <dialogs.h>
  24. #include <windows.h>
  25. #include <menus.h>
  26. #include <events.h>
  27. #include <OSEvents.h>
  28. #include <Desk.h>
  29. #include <diskinit.h>
  30. #include <OSUtils.h>
  31. #include <resources.h>
  32. #include <toolutils.h>
  33. #include <AppleEvents.h>
  34. #include <EPPC.h>
  35. #include <GestaltEqu.h>
  36. #include <PPCToolbox.h> 
  37. #include <Processes.h>
  38. #include <Balloons.h>
  39. #include <ALiases.h>
  40. #include <Processes.h>
  41. #include <StandardFile.h>
  42. #include <Folders.h>
  43.  
  44. /* prototypes */
  45. void OpenMovable(void);
  46. void CloseMovable(void);
  47. void InitalizeApp(void);
  48. void DoDiskEvents(long dinfo);                              /* hi word is error code, lo word is drive number */
  49. void DrawMain(WindowPtr drawIt);
  50. void DrawMain2(WindowPtr drawIt);
  51. void DrawMovable(WindowPtr drawIt);
  52. Boolean DoSelected(long val);
  53. void InitAEStuff(void);
  54. void DoHighLevel(EventRecord *AERecord);
  55. void DoDaCall(MenuHandle themenu, long theit);
  56. pascal OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  57. pascal OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  58. pascal OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  59. pascal OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  60. void SampleHelpDialog(void);
  61. void SetModalButtonState(gInBackground);
  62.  
  63. /* one external */
  64. extern void _DataInit();                                    /* this is the C initialization code */
  65.  
  66. enum  {
  67.     kMBarID = 128
  68. };
  69. enum  {
  70.     kAppleMenu = 128, kFileMenu, kEditMenu, kToolsMenu
  71. };
  72. enum  {
  73.     kResumeMask = 1,                                        /* bit of message field for resume vs. suspend */
  74.     kSampHelp = 129, kAboutBox = 128, kHelpString = 128, kNewItem = 1, kOpenItem, kCloseItem, kSaveItem, kSaveAsItem, kFileBlank1,
  75.         kPageSetupItem, kPrintItem, kFileBlank2, kQuitItem, kBadSystem = 130, kGenStrings = 128, kMenuToggleStrings = 129,
  76.         kCloseButton = 128, kMyModalKind = 1000, kMyDocumentKind
  77. };
  78. enum  {
  79.     kItem1 = 1
  80. };
  81. enum  {
  82.     kCloseIt = 1, kOpenIt
  83. };
  84. struct AEinstalls {
  85.     AEEventClass theClass;
  86.     AEEventID theEvent;
  87.     EventHandlerProcPtr theProc;
  88. };
  89. typedef struct AEinstalls AEinstalls;
  90.  
  91. /* some globals */
  92. MenuHandle gAppleMenuHandle, gFileMenuHandle, gEditMenuHandle, gToolMenuHandle;
  93. Boolean gQuit, gInBackground;
  94. EventRecord gERecord;
  95. Point gSavedPoint;
  96. Boolean gSavedPos;
  97. AEDesc gTheAddress;
  98. ProcessSerialNumber gOurSN;
  99. short gHelpItem;
  100. /* this is our global to tell us if a movable modal is up*/
  101. Boolean gModalUp = false;
  102. unsigned long gMySleep = 30;
  103.  
  104. #pragma segment Main
  105. main()
  106. {
  107.     WindowPtr twindow;
  108.     UnloadSeg((Ptr)_DataInit);                              /* throw out setup code */
  109.     InitalizeApp();
  110.     UnloadSeg((Ptr)InitalizeApp);                           /* get rid of my initialization code */
  111.     do {
  112.         
  113.         WaitNextEvent(everyEvent, &gERecord, gMySleep, nil);
  114.         switch (gERecord.what) {
  115.             ProcPtr drawProc;
  116.             short tempKind;
  117.             case nullEvent:
  118.                 /* no nul processing in this sample */
  119.                 break;
  120.                 
  121.             case updateEvt:
  122.                 tempKind = ((WindowPeek)gERecord.message)->windowKind;
  123.                 /* Mkae sure it's my window before I jump through the refCon */
  124.                 /* Why, since DA's have they're own layer in 7.0? */
  125.                 /* BECAUSE there are other people in the universe who will */
  126.                 /* add things to your windowList.BalloonWriter, for example, */
  127.                 /* so you still need to be careful */
  128.                 if (tempKind == kMyModalKind || tempKind == kMyDocumentKind) {
  129.                     /* get the drawing proc from the refCon */
  130.                     drawProc = (ProcPtr)GetWRefCon((WindowPtr)gERecord.message);
  131.                     /* jump to it */
  132.                     drawProc((WindowPtr)gERecord.message);
  133.                 }
  134.                 break;
  135.                 
  136.             case mouseDown:
  137.                 /* first see where the hit was */
  138.                 /* When you first think about the Movable Modal issue, you may*/
  139.                 /* say to yerself "Hey!if there's a mouseDown all I have to do is*/
  140.                 /* see if it's in the portRect of the front window, and SysBeep if it isn't!" */
  141.                 /* Nah, too easy.Remember, you want a user to be able to switch out */
  142.                 /* of your application when a movable modal is up, so you still need */
  143.                 /* to call FindWindow and see if it was a hit in the desktop, other*/
  144.                 /* app window (same as desktop), or in the Help or Application menus. */
  145.                 /* So, we just check our gModalUp flag in any place where */
  146.                 /* window positions may shift, and sysbeep elsewhere */
  147.                 
  148.                 switch (FindWindow(gERecord.where, &twindow)) {
  149.                     
  150.                     case inDesk:                            /* if they hit in desk, then the process manager */
  151.                         break;                              /* will switch us out, we don't need to do anything */
  152.                         
  153.                     case inMenuBar:
  154.                         /* let Help and Application menus happen always */
  155.                         DoSelected(MenuSelect(gERecord.where));
  156.                         break;
  157.                         
  158.                     case inSysWindow:
  159.                         /* pass to the system */
  160.                         SystemClick(&gERecord, twindow);
  161.                         break;
  162.                         
  163.                     case inContent:
  164.                         /* Handle content and control clicks here */
  165.                         if (twindow != FrontWindow()) {
  166.                             if (!gModalUp) {
  167.                                 SelectWindow(twindow);      /* select the window */
  168.                                 SetPort(twindow);
  169.                             } else {
  170.                                 SysBeep(1);                 /* complain because they hit a back window with MM up */
  171.                             }
  172.                         } else {
  173.                             /* control tracking or whatever.In this simple sample I */
  174.                             /* only have one control possible, so deal with it */
  175.                             Point locPoint = gERecord.where;
  176.                             ControlHandle returnedControl;
  177.                             GlobalToLocal(&locPoint);
  178.                             if (FindControl(locPoint, twindow, &returnedControl)) {
  179.                                 if (TrackControl(returnedControl, locPoint, nil)) {
  180.                                     CloseMovable();
  181.                                 }
  182.                             }
  183.                         }
  184.                         break;
  185.                         
  186.                     case inDrag:
  187.                         if (twindow != FrontWindow() && gModalUp) {
  188.                             /* don't do anything, can't drag a back window */
  189.                             SysBeep(1);
  190.                         } else {
  191.                             DragWindow(twindow, gERecord.where, &qd.screenBits.bounds);
  192.                         }
  193.                         break;
  194.                         
  195.                     case inGrow:
  196.                         /* Call GrowWindow here if you have a grow box */
  197.                         break;
  198.                         
  199.                     case inGoAway:
  200.                         /* Click in Close box */
  201.                         break;
  202.                 }
  203.             case mouseUp:
  204.                 /* don't care */
  205.                 break;
  206.                 /* same action for key or auto key */
  207.             case keyDown:
  208.             case autoKey:
  209.                 if (gERecord.modifiers & cmdKey)
  210.                     DoSelected(MenuKey(gERecord.message & charCodeMask));
  211.                 break;
  212.                 
  213.             case keyUp:
  214.                 /* don't care */
  215.                 break;
  216.                 
  217.             case diskEvt:
  218.                 /* I don't do anything special for disk events, this just passes them */
  219.                 /* to a function that checks for an error on the mount */
  220.                 DoDiskEvents(gERecord.message);
  221.                 break;
  222.                 
  223.             case activateEvt:
  224.                 /* not doing anything on activates */
  225.                 break;
  226.                 
  227.             case networkEvt:
  228.                 /* don't care */
  229.                 break;
  230.                 
  231.             case driverEvt:
  232.                 /* don't care */
  233.                 break;
  234.                 
  235.             case app4Evt:
  236.                 /* If we're switching layers and I have my MModal up, I want to */
  237.                 /* change the state of the control */
  238.                 switch ((gERecord.message >> 24) & 0x0FF) {     /* high byte of message */
  239.                     
  240.                     case suspendResumeMessage:              /* suspend/resume is also an activate/deactivate */
  241.                         gInBackground = (gERecord.message & kResumeMask) == 0;
  242.                         /* set dim/enable on the control */
  243.                         SetModalButtonState(gInBackground);
  244.                         break;
  245.                         
  246.                 }
  247.                 break;
  248.                 
  249.                 /* This dispatches high level events (AppleEvents, for example) */
  250.                 /* to our dispatch routine.This is NEW in the event loop for */
  251.                 /* System 7 */
  252.             case kHighLevelEvent:
  253.                 DoHighLevel(&gERecord);
  254.                 break;
  255.             default:
  256.                 break;
  257.                 
  258.         }
  259.     }
  260.             while (gQuit != true);
  261. }
  262.  
  263. /* DoDaCall opens the requested DA.It's here as a seperate routine if you'd */
  264. /* like to perform some action or just know when a DA is opened in your */
  265. /* layer.Can be handy to track memory problems when a DA is opened */
  266. /* with an Option-open */
  267. void DoDaCall(MenuHandle themenu, long theit)
  268. {
  269.     long qq;
  270.     char DAname[255];
  271.     GetItem(themenu, theit, &DAname);
  272.     qq = OpenDeskAcc(DAname);
  273. }
  274.  
  275. /* end DoDaCall */
  276.  
  277. /* DoDiskEvents just checks the error code from the disk mount, */
  278. /* and puts up the 'Format' dialog (through DIBadMount) if need be */
  279. /* You can do much more here if you care about what disks are */
  280. /* in the drive */
  281. void DoDiskEvents(long dinfo)                               /* hi word is error code, lo word is drive number */
  282. {
  283.     short hival, loval, tommy;
  284.     Point fredpoint =  {
  285.         40, 40
  286.     };
  287.     hival = HiWord(dinfo);
  288.     loval = LoWord(dinfo);
  289.     if (hival != noErr)                                     /* something happened */ {
  290.         tommy = DIBadMount(fredpoint, dinfo);
  291.     }
  292. }
  293.  
  294. /* draws my window.Pretty simple */
  295. void DrawMain(WindowPtr drawIt)
  296. {
  297.     Handle theText;
  298.     WindowPtr tempWP;
  299.     GetPort(&tempWP);
  300.     BeginUpdate(drawIt);
  301.     SetPort(drawIt);
  302.     EraseRect(&drawIt->portRect);
  303.     theText = GetResource('TEXT', 128);
  304.     if (theText) {
  305.         Rect textRect;
  306.         HLock(theText);
  307.         HUnlock(theText);
  308.         textRect = drawIt->portRect;
  309.         InsetRect(&textRect, 20, 20);
  310.         TextBox(*theText, GetHandleSize(theText), &textRect, 0);
  311.         ReleaseResource(theText);
  312.     }
  313.     EndUpdate(drawIt);
  314.     SetPort(tempWP);
  315. }
  316. /* a second version for variety */
  317. void DrawMain2(WindowPtr drawIt)
  318. {
  319.     Handle theText;
  320.     WindowPtr tempWP;
  321.     GetPort(&tempWP);
  322.     
  323.     BeginUpdate(drawIt);
  324.     SetPort(drawIt);
  325.     EraseRect(&drawIt->portRect);
  326.     theText = GetResource('TEXT', 130);
  327.     if (theText) {
  328.         Rect textRect;
  329.         HLock(theText);
  330.         HUnlock(theText);
  331.         textRect = drawIt->portRect;
  332.         InsetRect(&textRect, 20, 20);
  333.         TextBox(*theText, GetHandleSize(theText), &textRect, 0);
  334.         ReleaseResource(theText);
  335.     }
  336.     EndUpdate(drawIt);
  337.     SetPort(tempWP);
  338. }
  339.  
  340. /* Draws the Movable Modal window contents */
  341. void DrawMovable(WindowPtr drawIt)
  342. {
  343.     WindowPtr tempWP;
  344.     Handle theText;
  345.     BeginUpdate(drawIt);
  346.     GetPort(&tempWP);
  347.     
  348.     SetPort(drawIt);
  349.     EraseRect(&drawIt->portRect);
  350.     theText = GetResource('TEXT', 129);
  351.     if (theText) {
  352.         Rect textRect;
  353.         HLock(theText);
  354.         HUnlock(theText);
  355.         textRect = drawIt->portRect;
  356.         InsetRect(&textRect, 20, 20);
  357.         TextBox(*theText, GetHandleSize(theText), &textRect, 0);
  358.         ReleaseResource(theText);
  359.     }
  360.     DrawControls(drawIt);
  361.     EndUpdate(drawIt);
  362.     SetPort(tempWP);
  363. }
  364.  
  365. /* my menu action taker.It returns a Boolean which I usually ignore, but it */
  366. /* mught be handy someday */
  367. Boolean DoSelected(long val)
  368. {
  369.     short loval, hival;
  370.     Boolean returnVal = false;
  371.     loval = LoWord(val);
  372.     hival = HiWord(val);
  373.     
  374.     switch (hival) {                                        /* switch off the menu number selected */
  375.         case kAppleMenu:                                    /* Apple menu */
  376.             if (loval != 1) {                               /* if this was not About, it's a DA */
  377.                 DoDaCall(gAppleMenuHandle, loval);
  378.             } else {
  379.                 Alert(kAboutBox, nil);                      /* do about box */
  380.             }
  381.             returnVal = true;
  382.             break;
  383.         case kFileMenu:                                     /* File menu */
  384.             switch (loval) {
  385.                 case kQuitItem:
  386.                     gQuit = true;                           /* onlyitem */
  387.                     returnVal = true;
  388.                     break;
  389.                 default:
  390.                     break;
  391.             }
  392.             break;
  393.             
  394.         case kEditMenu:
  395.             /* edit menu junk */
  396.             /* don't care */
  397.             break;
  398.             
  399.         case kToolsMenu:
  400.             /* add all your test stuff here */
  401.             if (gModalUp)
  402.                 CloseMovable();
  403.             else
  404.                 OpenMovable();
  405.             break;
  406.             
  407.         case kHMHelpMenuID:                                 /* Defined in Balloons.h */
  408.             /* I only care about this item.If anything else is returned here, I don't know what */
  409.             /* it is, so I leave it alone.Remember, the Help Manager chapter says that */
  410.             /* Apple reserves the right to add and change things in the Help menu */
  411.             if (loval == gHelpItem)
  412.                 SampleHelpDialog();
  413.             break;
  414.             
  415.     }
  416.     HiliteMenu(0);
  417.     return(returnVal);
  418. }
  419.  
  420. /* InitAEStuff installs my appleevent handlers */
  421. void InitAEStuff(void)
  422. {
  423.     static AEinstalls HandlersToInstall[] =  { {
  424.             kCoreEventClass, kAEOpenApplication, AEOpenHandler
  425.         },  {
  426.             kCoreEventClass, kAEOpenDocuments, AEOpenDocHandler
  427.         },  {
  428.             kCoreEventClass, kAEQuitApplication, AEQuitHandler
  429.         },  {
  430.             kCoreEventClass, kAEPrintDocuments, AEPrintHandler
  431.         }, 
  432.         /* The above are the four required AppleEvents. */
  433.         
  434.     };
  435.     
  436.     OSErr aevtErr = noErr;
  437.     long aLong = 0;
  438.     Boolean gHasAppleEvents = false;
  439.     /* Check this machine for AppleEvents.If they are not here (ie not 7.0)
  440.     * then we exit */
  441.     gHasAppleEvents = (Gestalt(gestaltAppleEventsAttr, &aLong) == noErr);
  442.     /* The following series of calls installs all our AppleEvent Handlers.
  443.     * These handlers are added to the application event handler list that 
  444.     * the AppleEvent manager maintains.So, whenever an AppleEvent happens
  445.     * and we call AEProcessEvent, the AppleEvent manager will check our
  446.     * list of handlers and dispatch to it if there is one.
  447.     */
  448.     if (gHasAppleEvents) {
  449.         register qq;
  450.         for (qq = 0; qq < ((sizeof(HandlersToInstall) / sizeof(AEinstalls))); qq++) {
  451.             aevtErr = AEInstallEventHandler(HandlersToInstall[qq].theClass, HandlersToInstall[qq].theEvent,
  452.                                             HandlersToInstall[qq].theProc, 0, false);
  453.             if (aevtErr) {
  454.                 ExitToShell();                              /* just fail, baby */
  455.             }
  456.         }
  457.     } else {
  458.         ExitToShell();
  459.     }
  460. }
  461.  
  462. /* end InitAEStuff */
  463. /* I'm not doing error handling in this sample for clarities sake, you should. Hah, */
  464. /* easy for me to say, huh? */
  465. void DoHighLevel(EventRecord *AERecord)
  466. {
  467.     
  468.     AEProcessAppleEvent(AERecord);
  469.     
  470. }
  471.  
  472. /* end DoHighLevel */
  473.  
  474. /* This is the standard Open Application event.*/
  475. pascal OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  476. {
  477. #pragma unused (messagein,reply,refIn)
  478.     Str255 theName;
  479.     WindowPtr myWindow, secondWindow;
  480.     /* we of course don't do anything here in this simple app */
  481.     /* except open our window */
  482.     myWindow = GetNewWindow(128, nil, (WindowPtr)-1);
  483.     ((WindowPeek)myWindow)->windowKind = kMyDocumentKind;
  484.     /* install drawing proc */
  485.     SetWRefCon(myWindow, (long)DrawMain);
  486.     /* open another one, so we can demonstrate shuffling inhibiting */
  487.     secondWindow = GetNewWindow(128, nil, (WindowPtr)-1);
  488.     ((WindowPeek)secondWindow)->windowKind = kMyDocumentKind;
  489.     /* install drawing proc */
  490.     SetWRefCon(secondWindow, (long)DrawMain2);
  491.     GetIndString(theName, kGenStrings, 1);
  492.     SetWTitle(secondWindow, theName);
  493.     SelectWindow(myWindow);
  494.     SetPort(myWindow);
  495.     return(noErr);
  496.     
  497. }
  498.  
  499. /* end AEOpenHandler */
  500.  
  501. /* Open Doc, opens our documents.Remember, this can happen at application start AND */
  502. /* anytime else.If your app is up and running and the user goes to the desktop, hilites one */
  503. /* of your files, and double-clicks or selects Open from the finder File menu this event */
  504. /* handler will get called. Which means you don't do any initialization of globals here, or */
  505. /* anything else except open then doc.*/
  506. /* SO-- Do NOT assume that you are at app start time in this */
  507. /* routine, or bad things will surely happen to you. */
  508.  
  509. pascal OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  510. {
  511. #pragma unused (messagein,refIn,reply)
  512.     /* we of course don't do anything here */
  513.     return(errAEEventNotHandled);                           /* we have no docs, so no odoc events should come to us */
  514. }
  515.  
  516. pascal OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  517. {                                                           /* no printing handler in yet, so we'll ignore this */
  518.     /* the operation is functionally identical to the ODOC event, with the additon */
  519.     /* of calling your print routine.*/
  520. #pragma unused (messagein,refIn,reply)
  521.     /* we of course don't do anything here */
  522.     return(errAEEventNotHandled);                           /* we have no docs, so no pdoc events should come to us */
  523. }
  524.  
  525. /* Standard Quit event handler, to handle a Quit event from the Finder, for example.*/
  526. /* ••••• DO NOT CALL EXITTOSHELL HERE ••••• or you will never have a happy life.*/
  527. pascal OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  528. {
  529. #pragma unused (messagein,refIn,reply)
  530.     
  531.     /* prepQuit sets the Stop flag for us.It does _NOT_ quit, you */
  532.     /* should NEVER quit from an AppleEvent handler.Calling */
  533.     /* ExitToShell here would blow things up */
  534.     gQuit = true;
  535.     return(noErr);
  536. }
  537.  
  538. /* This is my sample help dialog.Does not do anything, expand as you need */
  539. void SampleHelpDialog(void)
  540. {
  541.     DialogPtr tdial = GetNewDialog(kSampHelp, nil, (WindowPtr)-1);
  542.     short itemhit = 0;
  543.     while (itemhit != 1) {
  544.         ModalDialog((ModalFilterProcPtr)nil, &itemhit);
  545.     }
  546.     DisposDialog(tdial);
  547. }
  548.  
  549.  
  550. /* Opens the MModal dialog. */
  551. /* Just for grins, I'm also saving and restoring it's position in*/
  552. /* a very simple way */
  553. void OpenMovable(void)
  554. {
  555.     WindowPtr temp;
  556.     Str63 theWords;
  557.     temp = GetNewWindow(129, nil, (WindowPtr)-1);
  558.     /* install drawing proc */
  559.     SetWRefCon(temp, (long)DrawMovable);
  560.     
  561.     /* set the kind to my MModalwindow */
  562.     ((WindowPeek)temp)->windowKind = kMyModalKind;
  563.     gModalUp = true;
  564.     
  565.     /* add the go away button */
  566.     GetNewControl(kCloseButton, temp);
  567.     
  568.     /* change the menu item text */
  569.     GetIndString(theWords, kMenuToggleStrings, kCloseIt);
  570.     SetItem(gToolMenuHandle, kItem1, theWords);
  571.     
  572.     if (gSavedPos) {
  573.         /* move it to the saved position */
  574.         /* move it to 0,0 to avoid any math at all */
  575.         MoveWindow(temp, 0, 0, false);
  576.         MoveWindow(temp, gSavedPoint.h, gSavedPoint.v, false);
  577.     }
  578.     ShowWindow(temp);
  579.     /* kill all the menus except the Test, Help, and App */
  580.     DisableItem(gAppleMenuHandle, 0);
  581.     DisableItem(gFileMenuHandle, 0);
  582.     DisableItem(gEditMenuHandle, 0);
  583.     DrawMenuBar();
  584.     SetPort(temp);
  585. }
  586.  
  587. void CloseMovable(void)
  588. {
  589.     Str63 theWords;
  590.     WindowPtr temp = FrontWindow();
  591.     /* the front window really should be my modal window */
  592.     /* if it isn't, I'm bailing.*/
  593.     gSavedPos = true;
  594.     gSavedPoint.h = temp->portRect.left;
  595.     gSavedPoint.v = temp->portRect.top;
  596.     LocalToGlobal(&gSavedPoint);
  597.     if (((WindowPeek)temp)->windowKind == kMyModalKind)
  598.         CloseWindow(temp);
  599.     else
  600.         gQuit = true;
  601.     
  602.     gModalUp = false;
  603.     
  604.     /* reset the menu item text */
  605.     GetIndString(theWords, kMenuToggleStrings, kOpenIt);
  606.     SetItem(gToolMenuHandle, kItem1, theWords);
  607.     /* turn our menus back on */
  608.     EnableItem(gAppleMenuHandle, 0);
  609.     EnableItem(gFileMenuHandle, 0);
  610.     EnableItem(gEditMenuHandle, 0);
  611.     DrawMenuBar();
  612. }
  613.  
  614. /* Dim the MModal button when we go into the background */
  615. void SetModalButtonState(gInBackground)
  616. {
  617.     WindowPtr theWindow = FrontWindow();
  618.     ControlHandle theControl;
  619.     short hState;
  620.     if (gModalUp) {
  621.         /* only if we exist, o' course */
  622.         if (((WindowPeek)theWindow)->windowKind == kMyModalKind) {
  623.             /* if this isn't true, then things are weird */
  624.             hState = (gInBackground ? 255 : 0);
  625.             theControl = ((WindowPeek)theWindow)->controlList;
  626.             HiliteControl(theControl, hState);
  627.             
  628.         }
  629.     }
  630. }
  631.  
  632.  
  633. #pragma segment Initialize
  634. void InitalizeApp(void)
  635. {
  636.     MenuHandle helpHandle;
  637.     Handle myMenu;
  638.     StringHandle helpString;
  639.     short count;
  640.     long vers;
  641.     MaxApplZone();
  642.     InitGraf((Ptr)&qd.thePort);
  643.     InitFonts();
  644.     InitWindows();
  645.     InitMenus();
  646.     TEInit();
  647.     InitDialogs(nil);
  648.     InitCursor();
  649.     /* Check system version */
  650.     Gestalt(gestaltSystemVersion, &vers);
  651.     vers = (vers >> 8) & 0xf;                               /* shift result over and mask out major version number */
  652.     if (vers < 7) {
  653.         StopAlert(kBadSystem, nil);
  654.         ExitToShell();
  655.     }
  656.     InitAEStuff();
  657.     /* set up my menu junk */
  658.     myMenu = GetNewMBar(kMBarID);
  659.     SetMenuBar(myMenu);
  660.     gAppleMenuHandle = GetMHandle(kAppleMenu);
  661.     gFileMenuHandle = GetMHandle(kFileMenu);
  662.     gEditMenuHandle = GetMHandle(kEditMenu);
  663.     gToolMenuHandle = GetMHandle(kToolsMenu);
  664.     AddResMenu(gAppleMenuHandle, 'DRVR');
  665.     /* now install my Help menu item in the Help Manager's menu */
  666.     HMGetHelpMenuHandle(&helpHandle);                       /* Get the Hlpe menu handle */
  667.     count = CountMItems(helpHandle);                        /* How many items are there? */
  668.     helpString = GetString(kHelpString);                    /* get my help string */
  669.     DetachResource(helpString);                             /* detach it */
  670.     HNoPurge(helpString);
  671.     MoveHHi((Handle)helpString);
  672.     HLock((Handle)helpString);
  673.     InsMenuItem(helpHandle, (Ptr)*helpString, count + 1);       /* insert my item in the Help menu */
  674.     gHelpItem = CountMItems(helpHandle);                    /* The number of the item */
  675.     
  676.     DrawMenuBar();
  677.     GetCurrentProcess(&gOurSN);                             /* Get our process serial number for later use, if needed */
  678.     
  679. }
  680.